package com.zsc.boot.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.boot.bean.Team;
import com.zsc.boot.bean.User;
import com.zsc.boot.bean.UserTeam;
import com.zsc.boot.bean.dto.TeamQuery;
import com.zsc.boot.bean.request.TeamAddRequest;
import com.zsc.boot.bean.request.TeamJoinRequest;
import com.zsc.boot.bean.request.TeamQuitRequest;
import com.zsc.boot.bean.request.TeamUpdateRequest;
import com.zsc.boot.bean.vo.TeamUserVO;
import com.zsc.boot.common.BaseResponse;
import com.zsc.boot.common.ErrorType;
import com.zsc.boot.common.ResultResponse;
import com.zsc.boot.exception.BusinessException;
import com.zsc.boot.service.TeamService;
import com.zsc.boot.service.UserService;
import com.zsc.boot.service.UserTeamService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/team")
@CrossOrigin(origins = { "http://www.academicnav.cn"}, allowCredentials = "true")
@Slf4j
public class TeamController {

    @Resource
    private TeamService teamService;

    @Resource
    private UserService userService;

    @Resource
    private UserTeamService userTeamService;

    /**
     * 创建（添加）队伍
     *
     * @param teamAddRequest
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Long> addTeam(@RequestBody TeamAddRequest teamAddRequest, HttpServletRequest request) {
        if (teamAddRequest == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        Team team = new Team();

        //将使用apache工具将teamAddRequest传给team
        try {
            BeanUtils.copyProperties(team, teamAddRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //调用业务逻辑层的方法进行校验与插入
        long teamId = teamService.createTeam(team, loginUser);
//        if (teamId == 0) {
//            throw new BusinessException(ErrorType.NULL_ERROR);
//        }
        //因为要返回的是添加成功数目，这里mybatis添加成功后会在属性上生成一个id
        return ResultResponse.success(teamId);
    }


    /**
     * 更新队伍
     *
     * @param teamUpdateRequest
     * @return
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> update(@RequestBody TeamUpdateRequest teamUpdateRequest, HttpServletRequest request) {
        if (teamUpdateRequest == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        boolean result = teamService.updateTeam(teamUpdateRequest, loginUser);
        if (!result) {
            throw new BusinessException(ErrorType.NULL_ERROR);
        }
        return ResultResponse.success(result);
    }

    /**
     * 根据id查询队伍
     *
     * @param id
     * @return
     */
    @GetMapping("/get")
    public BaseResponse<Team> getTeamById(Long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }
        Team team = teamService.getById(id);
        if (team == null) {
            throw new BusinessException(ErrorType.NULL_ERROR);
        }
        return ResultResponse.success(team);
    }

    /**
     * 查询所有队伍
     *
     * @param teamQuery：请求参数包装类
     * @return
     */
    @GetMapping("/list")
    public BaseResponse<List<TeamUserVO>> getTeamList(TeamQuery teamQuery, HttpServletRequest request) {
        if (teamQuery == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }

        User loginUser = userService.getLoginUser(request);
        boolean isAdmin = userService.isAdmin(request);
        //1、查询队伍列表
        List<TeamUserVO> teamUserVOList = teamService.listTeam(teamQuery,isAdmin);

        //下面这段逻辑是给前端退出按钮展示给已加入队伍的用户看的

        //获取到teamUserVOList的所有id并形成一个列表
        List<Long> teamIdList = teamUserVOList.stream().map(TeamUserVO::getId).collect(Collectors.toList());

        //2、判断当前用户是否已加入队伍
        QueryWrapper<UserTeam> userTeamQueryWrapper = new QueryWrapper<>();


        userTeamQueryWrapper.eq("userId",loginUser.getId());
        userTeamQueryWrapper.in("teamId",teamIdList);
        //当前用户已加入队伍的列表
        List<UserTeam> userTeamList = userTeamService.list(userTeamQueryWrapper);
        //获取当前用户已加入队伍的队伍id
        Set<Long> hasJoinTeamIdSet = userTeamList.stream().map(UserTeam::getTeamId).collect(Collectors.toSet());
        teamUserVOList.forEach(team ->{
            boolean hasJoin = hasJoinTeamIdSet.contains(team.getId());
            team.setHasJoin(hasJoin);
        });

        //3、查询加入队伍的用户人数
        QueryWrapper<UserTeam> userTeamJoinQueryWrapper = new QueryWrapper<>();
        userTeamJoinQueryWrapper.in("teamId",teamIdList);
        List<UserTeam> userTeamLists = userTeamService.list(userTeamJoinQueryWrapper);
        Map<Long, List<UserTeam>> joinTeamMap = userTeamLists.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        teamUserVOList.forEach(team ->{
            team.setJoinNum(joinTeamMap.getOrDefault(team.getId(),new ArrayList<>()).size());
        });


        return ResultResponse.success(teamUserVOList);
    }


    /**
     * 分页查询队伍
     *
     * @param teamQuery：请求参数包装类
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<Team>> getTeamListPage(TeamQuery teamQuery) {
        if (teamQuery == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }

        //team转化为teamQuery的操作，这里使用了apache的一个工具类进行转换
        Team team = new Team();
        try {
            BeanUtils.copyProperties(teamQuery, team);
        } catch (Exception e) {
            throw new BusinessException(ErrorType.SYSTEM_ERROR);
        }
        //使用teamService.list查询是发现接收的参数只能是team，所以要将team强转为teamQuery
        QueryWrapper<Team> queryWrapper = new QueryWrapper<>(team);

        Page<Team> page = new Page<>(teamQuery.getPageNum(), teamQuery.getPageSize());
        Page<Team> teamPage = teamService.page(page, queryWrapper);
        return ResultResponse.success(teamPage);
    }

    /**
     * 加入队伍
     * @param teamJoinRequest
     * @param request
     * @return
     */
    @PostMapping("/join")
    public BaseResponse<Boolean> joinTeam(@RequestBody TeamJoinRequest teamJoinRequest, HttpServletRequest request) {
        if (teamJoinRequest == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        boolean result = teamService.joinTeam(teamJoinRequest, loginUser);
        return ResultResponse.success(result);
    }

    /**
     * 用户退出队伍
     *
     * @param teamQuitRequest
     * @param request
     * @return
     */
    @PostMapping("/quit")
    public BaseResponse<Boolean> quitTeam(@RequestBody TeamQuitRequest teamQuitRequest, HttpServletRequest request) {
        if (teamQuitRequest == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }

        User loginUser = userService.getLoginUser(request);
        boolean result = teamService.quitTeam(teamQuitRequest, loginUser);
        return ResultResponse.success(result);
    }

    /**
     * 队长可解散队伍
     *
     * @param teamQuitRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> LeaderQuitTeam(@RequestBody TeamQuitRequest teamQuitRequest, HttpServletRequest request) {
        if (teamQuitRequest == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }

        User loginUser = userService.getLoginUser(request);
        boolean result = teamService.leaderQuitTeam(teamQuitRequest, loginUser);
        return ResultResponse.success(result);
    }

    /**
     * 查询我创建的队伍（查询team表中userId字段）
     * @param teamQuery
     * @param request
     * @return
     */
    @GetMapping("/list/my/create")
    public BaseResponse<List<TeamUserVO>> getMyCreateTeam(TeamQuery teamQuery, HttpServletRequest request) {
        if (teamQuery == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }

        User loginUser = userService.getLoginUser(request);
        teamQuery.setUserId(loginUser.getId());
        //这里设置管理员的权限为true，是因为我创建的队伍
        List<TeamUserVO> myTeamList = teamService.listMyCreateTeam(teamQuery);
        return ResultResponse.success(myTeamList);
    }

    /**
     * 查询我加入的队伍
     * @param teamQuery
     * @param request
     * @return
     */
    @GetMapping("/list/my/join")
    public BaseResponse<List<TeamUserVO>> getMyJoinTeam(TeamQuery teamQuery, HttpServletRequest request) {
        if (teamQuery == null) {
            throw new BusinessException(ErrorType.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);

        QueryWrapper<UserTeam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",loginUser.getId());
        List<UserTeam> userTeamList = userTeamService.list(queryWrapper);//查询出来关系表中当前登录用户对应的id列表

        //将userId与对应的teamId进行对应的分组
        //下面的这一行代码：userId和对用的teamId进行分组，teamId为key，userId为value，就行形成下面类似例子
        //比如：userId=1的用户加入了，队伍2，3，4。就会表示为：2 => 1，3 => 1，4 => 1
        Map<Long, List<UserTeam>> listMap = userTeamList.stream().collect(Collectors.groupingBy(UserTeam::getTeamId));
        List<Long> idList = new ArrayList<>(listMap.keySet());
        teamQuery.setIdList(idList);

        //这里设置管理员的权限为true，是因为我创建的队伍
        List<TeamUserVO> myTeamList = teamService.listTeam(teamQuery, true);
        return ResultResponse.success(myTeamList);

    }


}

